//https://blog.csdn.net/tracydragonlxy/article/details/108829406
//https://blog.csdn.net/qq_44543508/article/details/95449363

//1.测试java中的equals和==
//2.测试java内存中的包装类常量池

//总结：
//1、基本数据类型不能使用equals方法比较，只有==比较，比较的是表面的值内容
//2、对引用类型进行比较时，==比较的是对象的地址；equals如果不重写，调用的也是==，但一般如Integer、String这样的类里都已经重写过了，比较的是表面值的内容。
//3、用final修饰的成员变量表示常量，String定义的时候自带final。
//4、Java中的包装类存在常量池，在自动装箱的过程中会使用到。四种整型的范围都是-128到127，Character的范围是0到127，Boolean为true和false，浮点型没有。
//5、String对象创建时，会先到常量池创建或是去找，当第二次创建相同的对象时，就指向相同的位置（除非new）。
//6、自动装箱时会调用Integer.valueOf方法。
//7、Integer的常量池范围是可以手动调整的。

public class equalTest {
    public static void main(String[] args) {

        //因为第一次创建时，发现常量池中没有，所以就在常量池中创建一个对象"abc"，第二次创建的时候就直接使用
        //s1和s2实际是同一个对象，地址值相同
        String s1 = "abc";
        String s2 = "abc";
        System.out.println(s1 == s2);//true
        System.out.println(s1.equals(s2));//true

        //因为有new，所以是在堆中创建了一个新的对象，地址不同
        String s3 = new String("abc");
        System.out.println(s3 == s1);//false

        //两个都是new的，是不同的对象
        String s4 = new String("abcd");
        String s5 = new String("abcd");
        System.out.println(s4 == s5);//false

        //因为Java的包装类缓存机制，Integer的缓存范围为-128到127
        //在自动装箱的过程中，会调用封装类的Integer.valueOf(int i)方法，如果i在IntegerCache.low和Integer.high的范围以内，就直接从Cache中获取对象，否则才会new一个新的对象
        Integer i1 = 100;
        Integer i2 = 100;
        System.out.println(i1 == i2);//true
        System.out.println(i1.equals(i1));//true

        //129不在Cache的范围内，所以i3和i4都是new的新对象，地址不同
        Integer i3 = 129;
        Integer i4 = 129;
        System.out.println(i3 == i4);//false
        System.out.println(i3.equals(i4));//true
        //i5指向i3
        Integer i5 = i3;
        System.out.println(i5 == i3);//true
        System.out.println(i5.equals(i3));//true

        //i6的值虽然在Cache范围内，但此时用到了new，即是在创建一个新的对象，而不是自动装箱，所以i7和i6不是一个地址
        Integer i6 = new Integer(19);
        Integer i7 = 19;
        Integer i8 = new Integer(19);
        System.out.println(i6 == i7);//false
        System.out.println(16 == 18);//false

    }
}
